import asyncio

try:
    import uvloop

    asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
except ImportError:
    pass

from lib.myprocess import MyProcess
from server.rpc.rpcmanage import RpcManage
from server.rpc.server import RpcServer
import game
import g
from server import RedisDiscoverService
from server.rpc import DiscoverOption
import signal

Name = "worker"


async def get_all_service():
    """获取所有worker服务"""
    return await g.redis.hgetall(Name)


# 信号监听处理
def watch_signal():
    Handled_Signals = [
        signal.SIGTERM,
        signal.SIGINT,
    ]

    def sig_handle(*args):
        g.rpcManage.close()
        asyncio.gather(
            g.rpcServer.close(),
        )

    loop = asyncio.get_running_loop()
    try:
        for sig in Handled_Signals:
            loop.add_signal_handler(sig, sig_handle, sig)
    except NotImplementedError:
        # Windows
        for sig in Handled_Signals:
            signal.signal(sig, sig_handle)

    return "success"


async def _run(ip, port):
    g.workerAddress = f"{Name}_{ip}:{port}"
    g.init()

    # 服务发现配置
    discover_option = DiscoverOption(
        node_name=Name,
        instance=RedisDiscoverService(g.redis),
    )

    # rpc服务器
    rpcServer = g.rpcServer = RpcServer(
        ip,
        port,
        # server注册配置
        discover_option=discover_option,
    )
    # api路由
    rpcServer.route.add("api", game.do_api)

    # rpc调度器
    rpcManage = g.rpcManage = RpcManage(ip, port, discover_option, name=Name)
    await rpcManage.run()

    # 信号处理
    watch_signal()

    await asyncio.gather(
        rpcServer.run(),
        g.Model.run(),
    )


def run(ip, port, is_print=True):
    if is_print:
        print(f"启动子进程服务 {Name}_{ip}:{port}")
    try:
        asyncio.run(_run(ip, port))
    except KeyboardInterrupt:
        pass
    except asyncio.CancelledError:
        pass


def process_run(ip, port):
    process = MyProcess(f"{Name}_{ip}:{port}", run, ip, port, is_print=False)
    process.start()

    return process


if __name__ == '__main__':
    run("10.0.0.153", 9001)
